package cn.code.mycloud.module.envir.controller.admin.screen;

import cn.code.mycloud.framework.common.pojo.CommonResult;
import cn.code.mycloud.module.envir.dal.dataobject.aqi.AqiDO;
import cn.code.mycloud.module.envir.enums.DictTypeConstants;
import cn.code.mycloud.module.envir.service.aqi.AqiService;
import cn.code.mycloud.module.envir.service.grid.GridService;
import cn.code.mycloud.module.envir.service.usergrid.UserGridService;
import cn.code.mycloud.module.system.api.dict.DictDataApi;
import cn.code.mycloud.module.system.api.dict.dto.DictDataRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static cn.code.mycloud.framework.common.pojo.CommonResult.success;

@Tag(name = "可视化大屏")
@RestController
@RequestMapping("/envir/screen")
public class ScreenController {
    @Resource
    private AqiService aqiService;

    @Resource
    private GridService gridService;

    @Resource
    private UserGridService userGridService;

    @Resource
//    private DictDataService dictDataService;
    private DictDataApi dictDataApi; // openFeign

    @GetMapping("/hello")
    @Operation(summary = "hello")
    @PermitAll
    public CommonResult<String> hello() {
        return success("hello");
    }

    //    计算覆盖率
    private String getPercentage(List<Integer> cityIds) {
        HashSet<Long> set = new HashSet<>();
        // 查询所有网格记录
        gridService.selectAll().forEach(grid -> {
            if (cityIds.contains(grid.getCityId().intValue())) {
                set.add(grid.getCityId());
            }
        });
        // 统计大城市网格数量
        double size = set.size();

        // 计算覆盖率 总数/105
        double percentage = (size / (double) cityIds.size()) * 100.0;
        DecimalFormat df = new DecimalFormat("#.00");
        String formattedPercentage = df.format(percentage);
        return formattedPercentage;
    }

    //    全国省会城市网格覆盖率
    @GetMapping("/grid/coverage/capital_city")
    @Operation(summary = "全国省会城市网格覆盖率")
    @PermitAll
    public CommonResult<String> capitalCity() {
        String formattedPercentage = getPercentage(Constants.capitalCityIds);
        return success(formattedPercentage);
    }

    //    全国大城市网格覆盖率
    @GetMapping("/grid/coverage/big_city")
    @Operation(summary = "全国大城市网格覆盖率")
    @PermitAll
    public CommonResult<String> bigCity() {
        String formattedPercentage = getPercentage(Constants.bigCityIds);
        return success(formattedPercentage);
    }

    //    空气质量指数级别分布
    @GetMapping("/aqi/distribution/level")
    @Operation(summary = "空气质量指数级别分布")
    @PermitAll
    public CommonResult<Map<String, Long>> aqiLevel() {

        List<AqiDO> aqiDOS = aqiService.selectAllDone();
        // 空气质量等级列表，确保包含了所有可能的等级
//        List<DictDataDO> dictDataList = dictDataService.getDictDataList(CommonStatusEnum.ENABLE.getStatus(), DictTypeConstants.ENVIR_AQI_LEVEL);
//        List<String> allLevels = dictDataList.stream().map(DictDataDO::getValue).collect(Collectors.toList());
        CommonResult<List<DictDataRespDTO>> dictDataListResult = dictDataApi.getDictDataList(DictTypeConstants.ENVIR_AQI_LEVEL);
        List<String> allLevels = dictDataListResult.getData().stream().map(DictDataRespDTO::getValue).collect(Collectors.toList());

        // 首先计算已存在的aqiLevel及其数量
        Map<String, Long> groupSizeByAqiLevel = aqiDOS.stream()
                .collect(Collectors.groupingBy(AqiDO::getAqiLevelConfirm, Collectors.counting()));

        // 使用HashMap以允许插入缺失的等级
        Map<String, Long> completeGroupSize = new HashMap<>(groupSizeByAqiLevel);

        // 确保所有等级都出现在结果中，缺失的等级计数为0
        for (String level : allLevels) {
            completeGroupSize.putIfAbsent(level, 0L);
        }

        // 打印完整分布，包含所有等级及它们的数量
//        completeGroupSize.forEach((level, count) ->
//                envir.out.println("Aqi Level: " + level + ", Count: " + count)
//        );

        return success(completeGroupSize);
    }
    //    12个月内空气质量超标趋势
    @GetMapping("/aqi/overshoot/12/trend")
    @Operation(summary = "12个月内空气质量超标趋势")
    @PermitAll
    public CommonResult<List> aqiOvershoot12Trend() {

        List<AqiDO> aqiDOS = aqiService.selectAllDone();
        // 假定当前时间为参考点，回溯12个月
        LocalDate now = LocalDate.now();
        LocalDate twelveMonthsAgo = now.minusMonths(11);

        // 初始化每个月份的超标计数为0
        Map<Integer, Integer> monthlyExceedanceCount = new LinkedHashMap<>();

        LocalDate current = twelveMonthsAgo;
        while (!current.isAfter(now)) {
            monthlyExceedanceCount.put(current.getMonth().getValue(), 0);
            current = current.plusMonths(1);
        }

        // 将Date转换为LocalDate以便于日期操作（假设aqiDO.date是Date类型）
        List<AqiDO> recentAqiData = aqiDOS.stream()
                .filter(aqiDO -> {
                    LocalDate date = aqiDO.getCreateTime().atZone(ZoneId.systemDefault()).toLocalDate();
                    return date.isAfter(twelveMonthsAgo) && date.isBefore(now);
                })
                .collect(Collectors.toList());

        // 按月份分组统计超标天数

        for (AqiDO aqiDO : recentAqiData) {
            LocalDate date = aqiDO.getCreateTime().atZone(ZoneId.systemDefault()).toLocalDate();
            int month = date.getMonthValue();
            if (aqiDO.getAqiConfirm() > 50) { // 检查是否超标
                monthlyExceedanceCount.put(month, monthlyExceedanceCount.getOrDefault(month, 0) + 1);
            }
        }

        List result = new ArrayList();
        Map resultMap;
        // 输出结果，当前月会作为循环的最后一次迭代处理，自然位于末尾
        for (Map.Entry<Integer, Integer> entry : monthlyExceedanceCount.entrySet()) {
            resultMap = new HashMap();
            resultMap.put("month", entry.getKey());
            resultMap.put("count", entry.getValue());
//            envir.out.println("Month: " + entry.getKey() + ", Exceedance Count: " + entry.getValue());
            result.add(resultMap);
        }

        return success(result);
    }

    //    空气质量监测总数量
    @GetMapping("/aqi/total")
    @Operation(summary = "空气质量监测总数量")
    @PermitAll
    public CommonResult<Integer> aqiTotal() {
        List<AqiDO> aqiDOS = aqiService.selectAll();
        return success(aqiDOS.size());
    }
    //    空气质量监测良好
    @GetMapping("/aqi/total_good")
    @Operation(summary = "空气质量监测良好")
    @PermitAll
    public CommonResult<Integer> aqiTotalGood() {
        List<AqiDO> aqiDOS = aqiService.selectAllDone();
        aqiDOS.removeIf(aqiDO -> aqiDO.getAqiConfirm() > 50);
        return success(aqiDOS.size());
    }

    //    空气质量监测污染
    @GetMapping("/aqi/total_bad")
    @Operation(summary = "空气质量监测污染")
    @PermitAll
    public CommonResult<Integer> aqiTotalBad() {
        List<AqiDO> aqiDOS = aqiService.selectAllDone();
        aqiDOS.removeIf(aqiDO -> aqiDO.getAqiConfirm() <= 50);
        return success(aqiDOS.size());
    }
    //    pm2.5超标总数
    @GetMapping("/aqi/overshoot/pm25/total")
    @Operation(summary = "pm2.5超标总数")
    @PermitAll
    public CommonResult<Map<String, Long>> aqiPM25Total() {
//        按每个省分组
        Map<String, Long> aqiDOSByProvince = aqiService.selectOneAqiWithProvince("pm25_confirm");
//        遍历每个省下的aqiDO，判断是否超标，需要重新计算
        return success(aqiDOSByProvince);
    }
   //    so2超标总数
    @GetMapping("/aqi/overshoot/so2/total")
    @Operation(summary = "so2超标总数")
    @PermitAll
    public CommonResult<Map<String, Long>> aqiSO2Total() {
//        按每个省分组
        Map<String, Long> aqiDOSByProvince = aqiService.selectOneAqiWithProvince("so2_confirm");
//        遍历每个省下的aqiDO，判断是否超标，需要重新计算
        return success(aqiDOSByProvince);
    }
   //    co超标总数
    @GetMapping("/aqi/overshoot/co/total")
    @Operation(summary = "co超标总数")
    @PermitAll
    public CommonResult<Map<String, Long>> aqiCOTotal() {
//        按每个省分组
        Map<String, Long> aqiDOSByProvince = aqiService.selectOneAqiWithProvince("co_confirm");
//        遍历每个省下的aqiDO，判断是否超标，需要重新计算
        return success(aqiDOSByProvince);
    }

    //    全国各省AQI超标总数
    @GetMapping("/aqi/overshoot/all/total")
    @Operation(summary = "全国各省AQI超标总数")
    @PermitAll
    public CommonResult<Map<String, Long>> aqiAllTotal() {
//        按每个省分组
        Map<String, Long> aqiDOSByProvince = aqiService.selectAllAqiWithProvince();
//        遍历每个省下的aqiDO，判断是否超标，需要重新计算
        return success(aqiDOSByProvince);
    }


}
